#if !defined(__READER_H_INCLUDED)
#define __READER_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "helper.h"

#define SCAN_BUFFER_SIZE	512

///////////////////////////////////////////////////////////////
class CReader
{
public:
  CReader();
  ~CReader();
  BOOL Open(LPCTSTR pszFileName);
  void Close();
  LONGLONG SetPointer(LONGLONG llMove, DWORD dwMoveMethod);
  BOOL Read(LPBYTE pbBuff, DWORD cbBuff, LPDWORD pdwRead, BOOL freeBlocks=TRUE);
  BOOL GetFromBuffer(LPBYTE pbBuff, DWORD cbBuff, LPDWORD pdwRead, BOOL freeBlocks=TRUE);
  void FreeBuffer(LONGLONG start=MAXLONGLONG); // frees all blocks before start
  LONGLONG GetSize();
  void StartPreRead();

  LONGLONG ScanAudioHeader(); /* scan MPEG Audio Header from Current Pointer */
  LONGLONG ScanAudioHeader(int nVersion, int nLayer);

  BOOL IsOpened()
  {
    return m_hFile == INVALID_HANDLE_VALUE ? FALSE : TRUE;
  }

  struct MEMBLOCK
  {
    void *data;             // Read data
    LONGLONG start;         // First read byte
    LONGLONG end;           // Last read byte
  };
  MEMBLOCK **m_blocks;        // Array of available blocks

  int      m_firstBlock;      // Index of first used block
  int      m_nextBlock;       // Index of next block to read
  int      m_blockCount;      // Number of blocks in array
  int      m_usedBlocks;      // Number of used blocks in array
  BOOL     m_preReadActive;   // Prereading active
  LONGLONG m_readPos;         // File position for pre-read
  LONGLONG m_seekPos;         // File position for "public" read
  LONGLONG m_fileSize;        // File size

  CCritSec m_csec;            // Critical section for multithreading locks
  HANDLE   m_hFile;           // File handle
  HANDLE   m_hPreReadThread;
  HWND     m_hwndMessage;
};

#endif //!__READER_H_INCLUDED
